package com.emokili.ewa.core.frame.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emokili.ewa.core.frame.entity.MemberEntity;
import com.emokili.ewa.common.exception.BizCodeEnum;
import com.emokili.ewa.common.exception.BusinessException;
import com.emokili.ewa.common.utils.JsonUtils;
import com.emokili.ewa.common.vo.MemberLoginVo;
import com.emokili.ewa.common.vo.MemberRegisterVo;
import com.emokili.ewa.common.vo.MemberUpdateVo;
import com.emokili.ewa.core.frame.dao.MemberDao;
import com.emokili.ewa.core.frame.service.MemberService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.repository.query.Param;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.emokili.ewa.common.exception.BizCodeEnum.LOGIN_OR_PASSWORD_ERROR;

/**
 * @author yuepanpan
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
    @Value("${REDIS_USER_SESSION_KEY}")
    private String REDIS_USER_SESSION_KEY;

    @Value("${SSO_SESSION_EXPIRE}")
    private Integer SSO_SESSION_EXPIRE;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void register(MemberRegisterVo vo) {
        checkEmailUnique(vo);
        checkUserNameUnique(vo);
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setFirstName(vo.getFirstName());
        memberEntity.setLastName(vo.getLastName());
        memberEntity.setCountry(vo.getCountry());
        memberEntity.setEmail(vo.getEmail());
        memberEntity.setUserName(vo.getUserName());
        memberEntity.setNickName(vo.getUserName());
        memberEntity.setCreateTime(new Date());
        memberEntity.setUpdateTime(new Date());
        memberEntity.setAcceptFriend("on");
        //密码进行MD5加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(vo.getPassword());
        memberEntity.setPassword(encode);
        save(memberEntity);
    }

    @Override
    public void checkUserNameUnique(MemberRegisterVo vo) {
        int existUserNameCount = this.count(new QueryWrapper<MemberEntity>().eq("userName", vo.getUserName()));
        if (existUserNameCount > 0) {
            throw new BusinessException(BizCodeEnum.USER_EXIST_EXCEPTION);
        }
    }

    @Override
    public void checkEmailUnique(MemberRegisterVo vo) {
        int existEmailCount = this.count(new QueryWrapper<MemberEntity>().eq("email", vo.getEmail()));
        if (existEmailCount > 0) {
            throw new BusinessException(BizCodeEnum.EMAIL_EXIST_EXCEPTION);
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo vo) {
        String loginAcct = vo.getEmail();
        String password = vo.getPassword();
        //1、去数据库查询 SELECT * FROM ums_member WHERE username = ? OR email = ?
        MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>()
                .eq("user_name", loginAcct).or().eq("email", loginAcct));
        if (memberEntity == null) {
            throw new BusinessException(LOGIN_OR_PASSWORD_ERROR);
        }
        String passwordByDataBase = memberEntity.getPassword();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //进行密码匹配
        boolean matches = passwordEncoder.matches(password, passwordByDataBase);
        if (!matches) {
            //密码匹配不上
            throw new BusinessException(LOGIN_OR_PASSWORD_ERROR);
        }
        //登录成功
        return memberEntity;
    }

    @Override
    public MemberEntity update(MemberUpdateVo vo) {
        if (StringUtils.isNotEmpty(vo.getEmail())) {
            //1、去数据库查询 SELECT * FROM ums_member WHERE username = ? OR email = ?
            MemberEntity entity = baseMapper.selectOne(new QueryWrapper<MemberEntity>()
                    .eq("email", vo.getEmail()));
            if (entity != null) {
                throw new BusinessException();
            }
        }
        MemberEntity memberEntity = new MemberEntity();
        BeanUtils.copyProperties(vo, memberEntity);
        updateById(memberEntity);
        MemberEntity byId = getById(memberEntity.getId());
        return byId;
    }

    @Override
    public MemberEntity getUserByToken(String token) {
        String json = stringRedisTemplate.opsForValue().get(REDIS_USER_SESSION_KEY + ":" + token);
        //判断是否为空
        if (StringUtils.isBlank(json)) {
            //todo 400, "此session已经过期，请重新登录"
            throw new BusinessException();
        }
        stringRedisTemplate.opsForValue().set(REDIS_USER_SESSION_KEY + ":" + token, json, SSO_SESSION_EXPIRE, TimeUnit.DAYS);
        MemberEntity memberEntity = JsonUtils.jsonToPojo(json, MemberEntity.class);
        return memberEntity;
    }

    @Override
    public MemberEntity getMemberInfoBySerialNumber(Long serialNumber) {
        MemberEntity memberEntity = baseMapper.getMemberInfoBySerialNumber(serialNumber);
        return memberEntity;
    }


}
